% Copyright (c) 2007-2009 Nokia Corporation
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
%     http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.


\section{\module{positioning} ---
         Simplified interface to the position information}
\label{sec:position}

\declaremodule{extension}{positioning}		% not standard, in C
\platform{S60}
\modulesynopsis{Simplified interface to the position information.}

The \module{positioning} module provides basic access to the S60 position 
information \footnote{For details, please see the Location Acquisition API in 
the S60 API documentation. The Location Acquisition API gathers different 
positioning technologies together to be used through a consistent interface.}. 
The module can be e.g. used to access position information provided by external 
Bluetooth GPS-devices and by built-in GPS-receivers\footnote{For more 
information on GPS, please see 
\url{http://en.wikipedia.org/wiki/Global_Positioning_System}.} from S60 devices.

The module offers a large amount of information (cost of service, device power 
consumption etc.) about accessible positioning devices (like GPS-modules), 
position, course, accuracy and satellite information (depending on the position 
device used) and much more. This module can also be used to obtain device/vendor 
specific extended information.

\begin{notice}[note]
The  module \module{position} requires Location capability.
\end{notice}

The following data items are available in \module{positioning}:

\begin{datadesc}{POSITION_INTERVAL}
The time interval (in microseconds) between the \code{position} function 
callback invocation. The default value set is 1000000 microseconds (= 1 
second)
\end{datadesc}

The \module{positioning} module has the following functions (for examples of the 
values returned, see Section \ref{position-example}):

\begin{funcdesc}{modules}{}
Get information about available positioning modules.
\end{funcdesc}

\begin{funcdesc}{default_module}{}
Get default module id.
\end{funcdesc}

\begin{funcdesc}{module_info}{module_id}
Get detailed information about the specified module.
\end{funcdesc}

\begin{funcdesc}{select_module}{module_id}
Select a module.
\end{funcdesc}

\begin{funcdesc}{set_requestors}{requestors}
Set the \var{requestors} of the service (at least one must be set).
\end{funcdesc}

\begin{funcdesc}{position}{course=0,satellites=0,callback=None,
                          interval=positioning.POSITION_INTERVAL, partial=0}

By default, returns the position information in a dictionary. With \var{course} 
and/or \var{satellites} set to 1, information about course and satellites is 
also returned (if available).

With no \var{callback} provided, this call blocks until the position information 
is available.

The call returns immediately if a valid \var{callback} function is given. This 
\var{callback} function is then invoked with the specified time \var{interval} 
(in microseconds) in between the invocations. The \var{callback} function is 
called with the the current position information as parameter.

If \var{partial} update is set to 1, the function might return e.g. information 
about satellites before the final location fix has been calculated.

For an example of the dictionary returned and the detailed keys, see Section 
\ref{position-example}.

\end{funcdesc}

\begin{funcdesc}{stop_position}{}
Stops an ongoing \code{position} request.
\end{funcdesc}

\begin{funcdesc}{last_position}{}
Get last position information. 
This method returns the cached position information if it is available.
\end{funcdesc}

\subsection{Example \label{position-example}}

The following example (invoked in a Nokia N95 device) demonstrates how to use 
the Python \module{positioning} module to obtain information about the 
positioning technologies in the device:

\begin{verbatim}
>>> import positioning
>>> positioning.modules()
[{'available': 0, 'id': 270526873, 'name': u'Bluetooth GPS'}, {'available': 1, '
id': 270526858, 'name': u'Integrated GPS'}, {'available': 1, 'id': 270559509, 'n
ame': u'Network based'}]
>>> positioning.default_module()
270526858
>>> positioning.module_info(270526858)
{'available': 1, 'status': {'data_quality': 3, 'device_status': 7}, 'version': u
'1.00(0)', 'name': u'Integrated GPS', 'position_quality': {'vertical_accuracy':
10.0, 'time_to_first_fix': 1000000L, 'cost': 1, 'time_to_next_fix': 1000000L, 'h
orizontal_accuracy': 10.0, 'power_consumption': 3}, 'technology': 1, 'id': 27052
6858, 'capabilities': 127, 'location': 1}
>>>
\end{verbatim}

The following example demonstrates how to use the Python \module{positioning} 
module.

\begin{verbatim}
# information about available positioning modules
print "***available modules***"
print positioning.modules()
print ""

# id of the default positioning module
print "***default module***"
print positioning.default_module()
print ""

# detailed information about the default positioning module
print "***detailed module info***"
print positioning.module_info(positioning.default_module())
print ""

# select a module (in practise, selecting default module has no 
# relevance.). 
positioning.select_module(positioning.default_module())

# set requestors.
# at least one requestor must be set before requesting the 
# current position or last position.
# the last requestor must always be service requestor 
# (whether or not there are other requestors). 
positioning.set_requestors([{"type":"service",
                             "format":"application",
                             "data":"test_app"}])
                            
# get the last position.
print positioning.last_position()
\end{verbatim}

An example dictionary returned/printed from the above call to last_position
function could be as follows

\begin{verbatim}
{'vertical_accuracy':59.0,'time':1206530248.329,'latitude':12.956741,'altitude':
811.0,'horizontal_accuracy':41.77254404,'longitude':77.715568724}

# get the last position if the device's position has not previously been 
# discovered.
print positioning.last_position()
\end{verbatim}

An example dictionary returned/printed from the above call to last_position
function could be as follows

\begin{verbatim}
{'vertical_accuracy':NaN,'time':1206530248.329,'latitude':NaN,'altitude':NaN,
'horizontal_accuracy':NaN,'longitude':NaN}

# Example 1. Blocking call

# get the position. 
# note that the first position()-call may take a long time
# (because of gps technology).
print "***position info***"                         
print positioning.position()
print ""

# re-get the position.
# this call should be much quicker.
# ask also course and satellite information.
print "***course and satellites***" 
print positioning.position(course=1,satellites=1)
print ""

# Example 2. Non-blocking call

def cb(event):
    print "---"
    print event
    print "---"

print "***starts the position feed***" 
print positioning.position(course=1,satellites=1,
                           callback=cb, interval=500000,
                           partial=0)
\end{verbatim}

An example dictionary returned/printed from the above example script could be 
as follows:

\begin{verbatim}
{'satellites': {'horizontal_dop': 2.34999990463257, 'used_satellites': 5, 'verti
cal_dop': 2.29999995231628, 'time': 1187167353.0, 'satellites': 11, 'time_dop':
1.26999998092651}, 'position': {'latitude': 60.217033666473, 'altitude': 42.0, '
vertical_accuracy': 58.0, 'longitude': 24.878942093007, 'horizontal_accuracy': 4
7.531005859375}, 'course': {'speed': 0.0500000007450581, 'heading': 68.959999084
4727, 'heading_accuracy': 359.989990234375, 'speed_accuracy': NaN}}
\end{verbatim}

To run the script in the emulator you must configure PSY emulation from your 
emulator (SimPSYConfigurator $\rightarrow$ Select Config File $\rightarrow$ 
\textless some config files\textgreater or Tools $\rightarrow$ Position).
